package com.sfl.api_backend.controller.files;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sfl.api_backend.constant.HttpCode;
import com.sfl.api_backend.entity.Datasets;
import com.sfl.api_backend.entity.Imgs;
import com.sfl.api_backend.entity.Labels;
import com.sfl.api_backend.entity.Labelsets;
import com.sfl.api_backend.service.IDatasetsService;
import com.sfl.api_backend.service.IImgsService;
import com.sfl.api_backend.service.ILabelsService;
import com.sfl.api_backend.service.ILabelsetsService;
import com.sfl.api_backend.utils.Api.RestResult;
import com.sfl.api_backend.utils.File.DeleteFilestore;
import com.sfl.api_backend.utils.RandomID;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 数据集表 控制器
 * </p>
 *
 * @author szc
 * @since 2023-01-27
 */

@RestController
@RequestMapping("/files/imgs/imgsets")
@ResponseBody
@Slf4j
public class DatasetsController {

    @Resource
    private IDatasetsService datasetsService;

    @Resource
    private ILabelsetsService labelsetsService;

    @Resource
    private ILabelsService labelsService;

    @Resource
    private IImgsService imgsService;

    @Value("${file.upload.path}")
    private String uploadPath;

    /**
     * <p>
     * 批量删除数据集
     * </p>
     *
     * @author szc
     * @since 2023-01-30
     */

    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('User')")
    public RestResult delete(@RequestBody List<Integer> imgsetIds) throws Exception {
        log.info("Delete imgsets: {}", imgsetIds);

        List<Datasets> datasets = datasetsService.listByIds(imgsetIds);
        List<Labelsets> labelsets = new ArrayList<>();

        for (Datasets dataset : datasets) {
            Wrapper<Labelsets> labelsetsWrapper = new LambdaQueryWrapper<>();
            ((LambdaQueryWrapper<Labelsets>) labelsetsWrapper).eq(Labelsets::getImgsetId, dataset.getImgsetId());
            labelsets.addAll(labelsetsService.list(labelsetsWrapper));
        }

        // get all labels
        List<Integer> labelIds = new ArrayList<>();
        for (Labelsets labelset : labelsets) {
            Wrapper<Labels> labelsWrapper = new LambdaQueryWrapper<>();
            ((LambdaQueryWrapper<Labels>) labelsWrapper).eq(Labels::getLabelsetId, labelset.getLabelsetId());
            List<Labels> labels = labelsService.list(labelsWrapper);
            for (Labels label : labels) {
                labelIds.add(label.getLabelId());
            }
        }

        // get all imgs
        List<Integer> imgIds = new ArrayList<>();
        for (Datasets vo : datasets) {
            Wrapper<Imgs> imgsWrapper = new LambdaQueryWrapper<>();
            ((LambdaQueryWrapper<Imgs>) imgsWrapper).eq(Imgs::getImgsetId, vo.getImgsetId());
            List<Imgs> imgs = imgsService.list(imgsWrapper);
            for (Imgs img : imgs) {
                imgIds.add(img.getImgId());
            }
        }

        for (Datasets dataset : datasets) {
            File file = new File(dataset.getImgsetPath());
            DeleteFilestore.deleteFile(file);
        }

        for (Labelsets labelset : labelsets) {
            File file = new File(labelset.getLabelsetPath());
            DeleteFilestore.deleteFile(file);
        }

        List<Integer> labelsetIds = new ArrayList<>();
        for (Labelsets labelset : labelsets) {
            labelsetIds.add(labelset.getLabelsetId());
        }
        labelsetsService.removeBatchByIds(labelsetIds);
        datasetsService.removeBatchByIds(imgsetIds);
        labelsService.removeBatchByIds(labelIds);
        imgsService.removeBatchByIds(imgIds);

        return RestResult.success();

    }

    @PostMapping("/modify")
    @PreAuthorize("hasAuthority('User')")
    public RestResult modifly(@RequestBody Datasets datasets){
        try {
            log.info("modify imgsets: {}", datasets.getImgsetId());
            Datasets tmpDatasets = datasetsService.getById(datasets.getImgsetId());

            if(!StringUtils.isEmpty(datasets.getImgsetName()))
                tmpDatasets.setImgsetName(datasets.getImgsetName());

            if(!StringUtils.isEmpty(datasets.getRepresent()))
                tmpDatasets.setRepresent(datasets.getRepresent());

            datasetsService.updateById(tmpDatasets);
            return RestResult.success();
        }
        catch (RuntimeException e) {
            log.error("modify imgsets: {} error", datasets.getImgsetId());
            return RestResult.error(HttpCode.NOT_IMPLEMENTED, e.getMessage());
        }
    }

    @PostMapping("/make")
    @PreAuthorize("hasAuthority('User')")
    public RestResult make(@RequestBody Datasets datasets){
        try {
            log.info("make imgsets: {}", datasets.getImgsetName());
            // set time
            LocalDateTime now = LocalDateTime.now();
            datasets.setCreateTime(now);
            // set id
            datasets.setImgsetId(RandomID.getRandomID());
            // set imgsetPath
            String imgsetPath = uploadPath + datasets.getUserId() + "/datasets/" + datasets.getImgsetId();
            String org_img = uploadPath + datasets.getUserId() + "/datasets/" + datasets.getImgsetId() + "/org_img/";
            String view_img = uploadPath + datasets.getUserId() + "/datasets/" + datasets.getImgsetId() + "/view_img/";
            datasets.setImgsetPath(imgsetPath);

            File file = new File(imgsetPath);
            File org_img_file = new File(org_img);
            File view_img_file = new File(view_img);

            if (!file.exists()) {
                file.mkdirs();
            }
            if (!org_img_file.exists()) {
                org_img_file.mkdirs();
            }
            if (!view_img_file.exists()) {
                view_img_file.mkdirs();
            }

            // save
            datasetsService.save(datasets);
            return RestResult.success();
        }
        catch (RuntimeException e) {
            log.error("make imgsets: {} error", datasets.getImgsetName());
            return RestResult.error(HttpCode.NOT_IMPLEMENTED, e.getMessage());
        }
    }

    @PostMapping("/list")
    @PreAuthorize("hasAuthority('User')")
    public RestResult list(@RequestBody Datasets datasets){
        try {
            log.info("list imgsets: {}", datasets.getUserId());
            Wrapper<Datasets> datasetsWrapper = new LambdaQueryWrapper<>();
            ((LambdaQueryWrapper<Datasets>) datasetsWrapper).eq(Datasets::getUserId, datasets.getUserId());

            var result = datasetsService.list(datasetsWrapper);
            return RestResult.success(result);
        }
        catch (RuntimeException e) {
            log.error("list imgsets: {} error", datasets.getUserId());
            return RestResult.error(HttpCode.NOT_IMPLEMENTED, e.getMessage());
        }
    }



}
